package com.chushouya.manager.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * RabbitMQ配置类
 * 可以通过配置 spring.rabbitmq.enabled=false 来禁用RabbitMQ
 */
@Configuration
@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "enabled", havingValue = "true", matchIfMissing = true)
public class RabbitMQConfig {

    // 文章相关队列常量
    public static final String ARTICLE_QUEUE = "article.queue";
    public static final String ARTICLE_EXCHANGE = "article.exchange";
    public static final String ARTICLE_ROUTING_KEY = "article.routing.key";
    
    // 延时队列相关常量
    public static final String DELAY_EXCHANGE = "delay.exchange";
    public static final String DELAY_QUEUE = "delay.queue";
    public static final String DELAY_ROUTING_KEY = "delay.routing.key";
    
    // 死信队列相关常量
    public static final String DEAD_LETTER_EXCHANGE = "dead.letter.exchange";
    public static final String DEAD_LETTER_QUEUE = "dead.letter.queue";
    public static final String DEAD_LETTER_ROUTING_KEY = "dead.letter.routing.key";

    // 定义文章队列
    @Bean
    public Queue articleQueue() {
        return QueueBuilder.durable(ARTICLE_QUEUE).build();
    }

    // 定义文章交换机
    @Bean
    public DirectExchange articleExchange() {
        return ExchangeBuilder.directExchange(ARTICLE_EXCHANGE).durable(true).build();
    }

    // 将队列与交换机绑定
    @Bean
    public Binding articleBinding() {
        return BindingBuilder.bind(articleQueue()).to(articleExchange()).with(ARTICLE_ROUTING_KEY);
    }
    
    // 定义死信交换机
    @Bean
    public DirectExchange deadLetterExchange() {
        return ExchangeBuilder.directExchange(DEAD_LETTER_EXCHANGE).durable(true).build();
    }
    
    // 定义死信队列
    @Bean
    public Queue deadLetterQueue() {
        return QueueBuilder.durable(DEAD_LETTER_QUEUE).build();
    }
    
    // 将死信队列绑定到死信交换机
    @Bean
    public Binding deadLetterBinding() {
        return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()).with(DEAD_LETTER_ROUTING_KEY);
    }
    
    // 定义延时交换机
    @Bean
    public DirectExchange delayExchange() {
        return ExchangeBuilder.directExchange(DELAY_EXCHANGE).durable(true).build();
    }
    
    // 定义延时队列，到期后消息会转发到死信交换机
    @Bean
    public Queue delayQueue() {
        Map<String, Object> args = new HashMap<>(3);
        // 设置死信交换机
        args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        // 设置死信路由键
        args.put("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY);
        // 不设置默认过期时间，通过消息属性单独设置
        return QueueBuilder.durable(DELAY_QUEUE).withArguments(args).build();
    }
    
    // 将延时队列绑定到延时交换机
    @Bean
    public Binding delayBinding() {
        return BindingBuilder.bind(delayQueue()).to(delayExchange()).with(DELAY_ROUTING_KEY);
    }

    // 消息转换器，使用JSON格式
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    private static final Logger logger = LoggerFactory.getLogger(RabbitMQConfig.class);
    
    // 配置RabbitTemplate
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        
        // 消息发送确认回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                logger.debug("消息发送成功，correlationData={}", correlationData);
            } else {
                logger.error("消息发送失败，correlationData={}, cause={}", correlationData, cause);
            }
        });
        
        // 消息发送失败返回回调
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            logger.error("消息路由失败：exchange={}, routingKey={}, replyCode={}, replyText={}, message={}", 
                    exchange, routingKey, replyCode, replyText, message);
        });
        
        logger.info("RabbitMQ配置初始化完成");
        return rabbitTemplate;
    }
}
